package org.obm.delivery.cassandra.impl;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;

import org.apache.james.mime4j.dom.Body;
import org.apache.james.mime4j.dom.Entity;
import org.apache.james.mime4j.dom.Message;
import org.apache.james.mime4j.dom.Multipart;
import org.apache.james.mime4j.dom.SingleBody;
import org.apache.james.mime4j.message.BodyPart;
import org.obm.bigg.model.Messages;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import fr.aliasource.utils.FileUtils;

public class StructureHelper {

	private Logger logger = LoggerFactory.getLogger(getClass());
	private Message m;
	private BlownUpMessage bum;
	private boolean bodySet;
	private String mime;
	private String filename;
	private String encoding;

	public StructureHelper(Message m, BlownUpMessage bum) {
		this.m = m;
		this.bum = bum;
		this.mime = m.getMimeType();
	}

	public void extractStructure() {
		Map<String, String> infos = bum.getMessagesInfo();
		logger.info("extracting bodies of " + m.getMessageId() + " "
				+ m.getMimeType());
		Body body = m.getBody();
		processBody(infos, body, false);
	}

	private void processBody(Map<String, String> infos, Body body,
			boolean inAlternatives) {
		if (body instanceof Message) {
			logger.info("found rfc822 attachment");
		} else if (body instanceof Multipart) {
			processMultipart(infos, (Multipart) body, inAlternatives);
		} else if (body instanceof SingleBody) {
			processSingleBody(infos, (SingleBody) body, inAlternatives);
		} else {
			logger.warn("Don't know how to process " + m.getMessageId()
					+ " body");
		}
	}

	private void processMultipart(Map<String, String> infos, Multipart mp,
			boolean inAlternatives) {
		// TODO Auto-generated method stub
		logger.info("processMultipart");
		List<Entity> list = mp.getBodyParts();
		for (Entity e : list) {
			if (e instanceof BodyPart) {
				BodyPart bp = (BodyPart) e;
				this.mime = bp.getMimeType();
				this.filename = bp.getFilename();
				this.encoding = bp.getContentTransferEncoding();
				if (mime.startsWith("text/")) {
					processBody(infos, bp.getBody(), inAlternatives);
					if (!inAlternatives) {
						break;
					}
				} else if ("multipart/alternative".equals(mime)) {
					logger.info("multipart/alternative");
					processBody(infos, bp.getBody(), true);
				} else {
					processAttachment(bp.getBody());
				}
			}
		}
	}

	private void processAttachment(Body body) {
		logger.info("process attachment m: " + mime + " f: " + filename
				+ " e: " + encoding);
		// TODO Auto-generated method stub

	}

	private void processSingleBody(Map<String, String> infos, SingleBody b,
			boolean inAlternatives) {
		try {
			InputStream in = b.getInputStream();
			if (!bodySet || inAlternatives) {
				if (mime.equals("text/plain")) {
					bodySet = true;
					infos.put(Messages.BODY_PLAIN, FileUtils.streamString(in,
							true));
					logger.info(" * plain body set");
				} else if (mime.equals("text/html")) {
					bodySet = true;
					infos.put(Messages.BODY_HTML, FileUtils.streamString(in,
							true));
					logger.info(" * html body set");
				} else {
					processAttachment(b);
				}
			} else {
				processAttachment(b);
			}
		} catch (IOException e) {
			logger.error("error getting content", e);
		}
	}

}
